
#ifndef __FRAGMENT_BASE_SHADOW_OMNI_H__
#define __FRAGMENT_BASE_SHADOW_OMNI_H__

/******************************************************************************\
*
* OpenGL
*
\******************************************************************************/

#ifdef OPENGL

/*
 */
#ifdef QUALITY_HIGH

/*
 */
#define SAMPLER_SHADOW_COLOR_OMNI sampler2DArray
#define SAMPLER_SHADOW_DEPTH_OMNI sampler2DArrayShadow

/*
 */
#define SAMPLER_SHADOW_OMNI_PCF \
	uniform samplerCube s_texture_12; \
	uniform sampler2DArrayShadow s_texture_13; \
	uniform sampler3D s_texture_14; \
	uniform samplerCube s_texture_15; \

/*
 */
half shadowOmni(sampler2DArrayShadow s_depth,samplerCube CubeLookup,float4 texcoord) {
	float3 sample_direction = abs(texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	float4 sample_texcoord = texture(CubeLookup,texcoord.xyz);
	sample_texcoord.w = -1.0f / sample_maximum + texcoord.w;
	sample_texcoord.z *= 65535.0f;
	half shadow = texture(s_depth,sample_texcoord);
	return saturate(shadow + s_light_shadow_iradius.y);
}

/*
 */
half3 VOmniShadowPCF(half3 color,sampler2DArrayShadow s_depth,samplerCube s_color,sampler3D s_noise,samplerCube CubeLookup,float4 texcoord,float3 direction) {
	half shadow = 0.0f;
	#ifdef USE_TESSELLATION && TESSELLATION
		float3 shadow_direction = mul3(s_imodelview,texcoord.xyz - s_light_shadow_offset);
		float4 sample_texcoord = float4(shadow_direction * s_light_shadow_depth_range.x,0.0f);
		float sample_range = s_light_shadow_depth_range.y;
	#else
		float4 sample_texcoord = texcoord;
		float sample_range = texcoord.w;
	#endif
	float3 sample_direction = abs(sample_texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	sample_texcoord = texture(CubeLookup,sample_texcoord.xyz);
	sample_texcoord.w = -1.0f / sample_maximum + sample_range;
	sample_texcoord.z *= 65535.0f;
	#ifdef QUALITY_HIGH
		half3 jitter_texcoord = half3(gl_FragCoord.xy * (1.0f / 16.0f),0.0f);
		sample_texcoord.xy -= s_light_shadow_iradius.z;
		#define SAMPLE { \
			half4 jitter = texture(s_noise,jitter_texcoord) * s_light_shadow_iradius.w; \
			shadow += texture(s_depth,float4(sample_texcoord.xy + jitter.xy,sample_texcoord.zw)); \
			shadow += texture(s_depth,float4(sample_texcoord.xy + jitter.zw,sample_texcoord.zw)); \
			jitter_texcoord.z += 1.0f / 16.0f; \
		}
		SAMPLE
		SAMPLE
		SAMPLE
		SAMPLE
		shadow *= 1.0f / 8.0f;
		#ifdef USE_SHADOW_KERNEL
			if(shadow * (1.0f - shadow) != 0.0f) {
				shadow *= 8.0f;
				for(int i = 4; i < 16; i++) {
					SAMPLE
				}
				shadow *= 1.0f / 32.0f;
				#ifdef SHOW_PENUMBRA
					color = half3(1.0f,0.0f,0.0f);
				#endif
			}
		#endif
		#undef SAMPLE
	#else
		shadow = texture(s_depth,sample_texcoord);
	#endif
	color *= saturate(shadow + s_light_shadow_iradius.y);
	#ifdef USE_TRANSLUCENT
		#ifdef USE_TESSELLATION && TESSELLATION
			sample_texcoord.xyz = shadow_direction * s_light_shadow_iradius.x;
		#else
			sample_texcoord.xyz = direction;
		#endif
		half sample_distance = saturate(length(half3(sample_texcoord.xyz)));
		half4 translucent = texture(s_color,sample_texcoord.xyz);
		if(shadow > 0.0f && sample_distance > translucent.w) color *= saturate(translucent.xyz + s_light_shadow_iradius.y);
	#endif
	return color;
}

/*
 */
half3 shadowOmniVertexPCF(half3 color,sampler2DArrayShadow s_depth,samplerCube s_color,sampler3D s_noise,samplerCube CubeLookup,float4 vertex) {
	float4 shadow_direction;
	float3 direction = mul3(s_imodelview,vertex.xyz - s_light_shadow_offset);
	shadow_direction.xyz = direction * s_light_shadow_depth_range.x;
	shadow_direction.w = s_light_shadow_depth_range.y;
	#ifdef USE_TRANSLUCENT
		direction *= s_light_shadow_iradius.x;
	#endif
	return VOmniShadowPCF(color,s_depth,s_color,s_noise,CubeLookup,shadow_direction,direction);
}

#else

/*
 */
#define SAMPLER_SHADOW_COLOR_OMNI samplerCube
#define SAMPLER_SHADOW_DEPTH_OMNI samplerCubeShadow

/*
 */
#define SAMPLER_SHADOW_OMNI_PCF \
	uniform samplerCube s_texture_12; \
	uniform samplerCubeShadow s_texture_13; \
	uniform sampler3D s_texture_14; \
	uniform samplerCube s_texture_15; \

/*
 */
half shadowOmni(samplerCubeShadow s_depth,samplerCube CubeLookup,float4 texcoord) {
	float3 sample_direction = abs(texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	float sample_compare = -1.0f / sample_maximum + texcoord.w;
	half shadow = texture(s_depth,float4(texcoord.xyz,sample_compare));
	return saturate(shadow + s_light_shadow_iradius.y);
}

/*
 */
half3 VOmniShadowPCF(half3 color,samplerCubeShadow s_depth,samplerCube s_color,sampler3D s_noise,samplerCube CubeLookup,float4 texcoord,float3 direction) {
	#ifdef USE_TESSELLATION && TESSELLATION
		float3 shadow_direction = mul3(s_imodelview,texcoord.xyz - s_light_shadow_offset);
		float4 sample_texcoord = float4(shadow_direction * s_light_shadow_depth_range.x,0.0f);
		float sample_range = s_light_shadow_depth_range.y;
	#else
		float4 sample_texcoord = texcoord;
		float sample_range = texcoord.w;
	#endif
	float3 sample_direction = abs(sample_texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	float sample_compare = -1.0f / sample_maximum + texcoord.w;
	half shadow = texture(s_depth,float4(sample_texcoord.xyz,sample_compare));
	color *= saturate(shadow + s_light_shadow_iradius.y);
	#ifdef USE_TRANSLUCENT
		#ifdef USE_TESSELLATION && TESSELLATION
			sample_texcoord.xyz = shadow_direction * s_light_shadow_iradius.x;
		#else
			sample_texcoord.xyz = direction;
		#endif
		half sample_distance = saturate(length(half3(sample_texcoord.xyz)));
		half4 translucent = texture(s_color,sample_texcoord.xyz);
		if(shadow > 0.0f && sample_distance > translucent.w) color *= saturate(translucent.xyz + s_light_shadow_iradius.y);
	#endif
	return color;
}

/*
 */
half3 shadowOmniVertexPCF(half3 color,samplerCubeShadow s_depth,samplerCube s_color,sampler3D s_noise,samplerCube CubeLookup,float4 vertex) {
	float4 shadow_direction;
	float3 direction = mul3(s_imodelview,vertex.xyz - s_light_shadow_offset);
	shadow_direction.xyz = direction * s_light_shadow_depth_range.x;
	shadow_direction.w = s_light_shadow_depth_range.y;
	#ifdef USE_TRANSLUCENT
		direction *= s_light_shadow_iradius.x;
	#endif
	return VOmniShadowPCF(color,s_depth,s_color,s_noise,CubeLookup,shadow_direction,direction);
}

#endif

/*
 */
#ifdef SHADOW
	#ifdef USE_TESSELLATION && TESSELLATION
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_texture_12,s_texture_14,s_texture_15,float4(s_texcoord_3.xyz,1.0f),half3(0.0f));
	#elif USE_TRANSLUCENT
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_texture_12,s_texture_14,s_texture_15,s_texcoord_4,s_texcoord_5.xyz);
	#else
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_texture_12,s_texture_14,s_texture_15,s_texcoord_4,float3(0.0f));
	#endif
#else
	#define SHADOW_OMNI_PCF(COLOR) { }
#endif

/*
 */
#ifdef SHADOW
	#define SHADOW_OMNI_VERTEX_PCF(COLOR,VERTEX) COLOR = shadowOmniVertexPCF(COLOR,s_texture_13,s_texture_12,s_texture_14,s_texture_15,VERTEX);
#else
	#define SHADOW_OMNI_VERTEX_PCF(COLOR,VERTEX) { }
#endif

/******************************************************************************\
*
* Direct3D11
*
\******************************************************************************/

#elif DIRECT3D11

/*
 */
#ifdef QUALITY_HIGH

/*
 */
#define TEXTURE_SHADOW_OMNI	Texture2DArray

/*
 */
#define TEXTURE_SHADOW_OMNI_PCF \
	TextureCube s_texture_12 : register(t12); \
	Texture2DArray s_texture_13 : register(t13); \
	Texture3D s_texture_14 : register(t14); \
	TextureCube s_texture_15 : register(t15);

/*
 */
half shadowOmni(Texture2DArray s_depth,SamplerState s_depth_sampler,SamplerComparisonState s_depth_sampler_compare,TextureCube CubeLookup,SamplerState CubeLookup_sampler,float4 texcoord) {
	float3 sample_direction = abs(texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	float sample_compare = -1.0f / sample_maximum + texcoord.w;
	float3 sample_clamp = 127.0f / 128.0f + (sample_direction == sample_maximum) / 128.0f;
	sample_direction = clamp(texcoord.xyz / sample_maximum,-sample_clamp,sample_clamp);
	float3 sample_texcoord = CubeLookup.Sample(CubeLookup_sampler,sample_direction).xyz;
	sample_texcoord.z *= 65535.0f;
	#ifdef USE_FEATURE_LEVEL_10_1
		half shadow = s_depth.SampleCmpLevelZero(s_depth_sampler_compare,sample_texcoord,sample_compare);
	#else
		half shadow = shadow2DArrayLinear(s_depth,s_depth_sampler,sample_texcoord,s_material_textures[4],sample_compare);
	#endif
	return saturate(shadow + s_light_shadow_iradius.y);
}

/*
 */
half3 VOmniShadowPCF(half3 color,Texture2DArray s_depth,SamplerState s_depth_sampler,SamplerComparisonState s_depth_sampler_compare,TextureCube s_color,SamplerState s_color_sampler,Texture3D s_noise,SamplerState s_noise_sampler,TextureCube CubeLookup,SamplerState CubeLookup_sampler,float4 position,float4 texcoord,float3 direction) {
	half shadow = 0.0f;
	#ifdef USE_TESSELLATION && TESSELLATION
		float3 shadow_direction = mul3(s_imodelview,texcoord.xyz - s_light_shadow_offset);
		float3 sample_texcoord = shadow_direction * s_light_shadow_depth_range.x;
		float sample_range = s_light_shadow_depth_range.y;
	#else
		float3 sample_texcoord = texcoord.xyz;
		float sample_range = texcoord.w;
	#endif
	float3 sample_direction = abs(sample_texcoord);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	float3 sample_clamp = 127.0f / 128.0f + (sample_direction == sample_maximum) * (1.0f / 128.0f);
	sample_direction = clamp(sample_texcoord / sample_maximum,-sample_clamp,sample_clamp);
	half sample_compare = -1.0f / sample_maximum + sample_range;
	sample_texcoord = CubeLookup.Sample(CubeLookup_sampler,sample_direction).xyz;
	sample_texcoord.z *= 65535.0f;
	half3 jitter_texcoord = half3(position.xy,0.0f) / 16.0f;
	sample_texcoord.xy -= s_light_shadow_iradius.z;
	#ifdef USE_FEATURE_LEVEL_10_1
		#define SAMPLE { \
			half4 jitter = s_noise.SampleLevel(s_noise_sampler,jitter_texcoord,0.0f) * s_light_shadow_iradius.w; \
			shadow += s_depth.SampleCmpLevelZero(s_depth_sampler_compare,sample_texcoord + half3(jitter.xy,0.0f),sample_compare); \
			shadow += s_depth.SampleCmpLevelZero(s_depth_sampler_compare,sample_texcoord + half3(jitter.zw,0.0f),sample_compare); \
			jitter_texcoord.z += 1.0f / 16.0f; \
		}
	#else
		#define SAMPLE { \
			half4 jitter = s_noise.SampleLevel(s_noise_sampler,jitter_texcoord,0.0f) * s_light_shadow_iradius.w; \
			shadow += (sample_compare < s_depth.SampleLevel(s_depth_sampler,sample_texcoord + half3(jitter.xy,0.0f),0.0f).x); \
			shadow += (sample_compare < s_depth.SampleLevel(s_depth_sampler,sample_texcoord + half3(jitter.zw,0.0f),0.0f).x); \
			jitter_texcoord.z += 1.0f / 16.0f; \
		}
	#endif
	SAMPLE
	SAMPLE
	SAMPLE
	SAMPLE
	shadow *= 1.0f / 8.0f;
	#ifdef USE_SHADOW_KERNEL
		[branch] if(shadow * (1.0f - shadow) != 0.0f) {
			shadow *= 8.0f;
			[unroll] for(int i = 4; i < 16; i++) {
				SAMPLE
			}
			shadow *= 1.0f / 32.0f;
			#ifdef SHOW_PENUMBRA
				color = half3(1.0f,0.0f,0.0f);
			#endif
		}
	#endif
	#undef SAMPLE
	color *= saturate(shadow + s_light_shadow_iradius.y);
	#ifdef USE_TRANSLUCENT
		#ifdef USE_TESSELLATION && TESSELLATION
			sample_texcoord = shadow_direction * s_light_shadow_iradius.x;
		#else
			sample_texcoord = direction;
		#endif
		half sample_distance = saturate(length(sample_texcoord));
		half4 translucent = s_color.Sample(s_color_sampler,sample_texcoord);
		[flatten] if(shadow > 0.0f && sample_distance > translucent.w) color *= saturate(translucent.xyz + s_light_shadow_iradius.y);
	#endif
	return color;
}

/*
 */
half3 shadowOmniVertexPCF(half3 color,Texture2DArray s_depth,SamplerState s_depth_sampler,SamplerComparisonState s_depth_sampler_compare,TextureCube s_color,SamplerState s_color_sampler,Texture3D s_noise,SamplerState s_noise_sampler,TextureCube CubeLookup,SamplerState CubeLookup_sampler,float4 position,float4 vertex) {
	float4 shadow_direction;
	float3 direction = mul3(s_imodelview,vertex.xyz - s_light_shadow_offset);
	shadow_direction.xyz = direction * s_light_shadow_depth_range.x;
	shadow_direction.w = s_light_shadow_depth_range.y;
	#ifdef USE_TRANSLUCENT
		direction *= s_light_shadow_iradius.x;
	#endif
	return VOmniShadowPCF(color,s_depth,s_depth_sampler,s_depth_sampler_compare,s_color,s_color_sampler,s_noise,s_noise_sampler,CubeLookup,CubeLookup_sampler,position,shadow_direction,direction);
}

#else

/*
 */
#define TEXTURE_SHADOW_OMNI	TextureCube

/*
 */
#define TEXTURE_SHADOW_OMNI_PCF \
	TextureCube s_texture_12 : register(t12); \
	TextureCube s_texture_13 : register(t13); \
	Texture3D s_texture_14 : register(t14); \
	TextureCube s_texture_15 : register(t15);

/*
 */
half shadowOmni(TextureCube s_depth,SamplerState s_depth_sampler,SamplerComparisonState s_depth_sampler_compare,TextureCube CubeLookup,SamplerState CubeLookup_sampler,float4 texcoord) {
	float3 sample_direction = abs(texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	float sample_compare = -1.0f / sample_maximum + texcoord.w;
	half shadow = s_depth.SampleCmpLevelZero(s_depth_sampler_compare,texcoord.xyz,sample_compare);
	return saturate(shadow + s_light_shadow_iradius.y);
}

/*
 */
half3 VOmniShadowPCF(half3 color,TextureCube s_depth,SamplerState s_depth_sampler,SamplerComparisonState s_depth_sampler_compare,TextureCube s_color,SamplerState s_color_sampler,Texture3D s_noise,SamplerState s_noise_sampler,TextureCube CubeLookup,SamplerState CubeLookup_sampler,float4 position,float4 texcoord,float3 direction) {
	half shadow = 0.0f;
	#ifdef USE_TESSELLATION && TESSELLATION
		float3 shadow_direction = mul3(s_imodelview,texcoord.xyz - s_light_shadow_offset);
		float3 sample_texcoord = shadow_direction * s_light_shadow_depth_range.x;
		float sample_range = s_light_shadow_depth_range.y;
	#else
		float3 sample_texcoord = texcoord.xyz;
		float sample_range = texcoord.w;
	#endif
	float3 sample_direction = abs(sample_texcoord);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	half sample_compare = -1.0f / sample_maximum + sample_range;
	shadow = s_depth.SampleCmpLevelZero(s_depth_sampler_compare,sample_texcoord,sample_compare);
	color *= saturate(shadow + s_light_shadow_iradius.y);
	#ifdef USE_TRANSLUCENT
		#ifdef USE_TESSELLATION && TESSELLATION
			sample_texcoord = shadow_direction * s_light_shadow_iradius.x;
		#else
			sample_texcoord = direction;
		#endif
		half sample_distance = saturate(length(sample_texcoord));
		half4 translucent = s_color.Sample(s_color_sampler,sample_texcoord);
		[flatten] if(shadow > 0.0f && sample_distance > translucent.w) color *= saturate(translucent.xyz + s_light_shadow_iradius.y);
	#endif
	return color;
}

/*
 */
half3 shadowOmniVertexPCF(half3 color,TextureCube s_depth,SamplerState s_depth_sampler,SamplerComparisonState s_depth_sampler_compare,TextureCube s_color,SamplerState s_color_sampler,Texture3D s_noise,SamplerState s_noise_sampler,TextureCube CubeLookup,SamplerState CubeLookup_sampler,float4 position,float4 vertex) {
	float4 shadow_direction;
	float3 direction = mul3(s_imodelview,vertex.xyz - s_light_shadow_offset);
	shadow_direction.xyz = direction * s_light_shadow_depth_range.x;
	shadow_direction.w = s_light_shadow_depth_range.y;
	#ifdef USE_TRANSLUCENT
		direction *= s_light_shadow_iradius.x;
	#endif
	return VOmniShadowPCF(color,s_depth,s_depth_sampler,s_depth_sampler_compare,s_color,s_color_sampler,s_noise,s_noise_sampler,CubeLookup,CubeLookup_sampler,position,shadow_direction,direction);
}

#endif

/*
 */
#ifdef SHADOW
	#ifdef USE_TESSELLATION && TESSELLATION
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_sampler_13,s_sampler_compare_13,s_texture_12,s_sampler_12,s_texture_14,s_sampler_14,s_texture_15,s_sampler_15,IN.position,float4(IN.texcoord_3,1.0f),0.0f);
	#elif USE_TRANSLUCENT
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_sampler_13,s_sampler_compare_13,s_texture_12,s_sampler_12,s_texture_14,s_sampler_14,s_texture_15,s_sampler_15,IN.position,IN.texcoord_4,IN.texcoord_5);
	#else
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_sampler_13,s_sampler_compare_13,s_texture_12,s_sampler_12,s_texture_14,s_sampler_14,s_texture_15,s_sampler_15,IN.position,IN.texcoord_4,0.0f);
	#endif
#else
	#define SHADOW_OMNI_PCF(COLOR) { }
#endif

/*
 */
#ifdef SHADOW
	#define SHADOW_OMNI_VERTEX_PCF(COLOR,VERTEX) COLOR = shadowOmniVertexPCF(COLOR,s_texture_13,s_sampler_13,s_sampler_compare_13,s_texture_12,s_sampler_12,s_texture_14,s_sampler_14,s_texture_15,s_sampler_15,IN.position,VERTEX);
#else
	#define SHADOW_OMNI_VERTEX_PCF(COLOR,VERTEX) { }
#endif

/******************************************************************************\
*
* Direct3D9
*
\******************************************************************************/

#elif DIRECT3D9


	


/*
 */
half shadowOmni(sampler s_depth,sampler CubeLookup,float4 texcoord,float4 texsize) 
{
	float3 sample_direction = abs(texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	#ifdef ATI_R700 || ATI_R800
		float3 sample_clamp = 127.0f / 128.0f + (sample_direction == sample_maximum) * (1.0f / 128.0f);
		sample_direction = clamp(texcoord.xyz / sample_maximum,-sample_clamp,sample_clamp);
	#else
		sample_direction = texcoord.xyz;
	#endif
	float4 sample_texcoord = float4(texCUBE(CubeLookup,sample_direction).xy,0.0f,1.0f);
	sample_texcoord.z = -1.0f / sample_maximum + texcoord.w;
	#ifdef HAS_NVIDIA_HARDWARE_SHADOW
		half shadow = tex2Dproj(s_depth,sample_texcoord).x;
	#elif HAS_ATI_HARDWARE_SHADOW
		half shadow = shadow2DLinear(s_depth,sample_texcoord.xy,texsize,sample_texcoord.z);
	#endif
	return saturate(shadow + s_light_shadow_iradius.y);
}


half sample_shadow(sampler2D depthMap, float3 position)
{
#if %_RT_HW_PCF_COMPARE
	shadow	= tex2Dproj(depthMap, float4 (p.xyz,1)).r;
#else
	shadow = tex2D( depthMap, p.xy ).r;
#endif
}






/*
 */
half3 VOmniShadowPCF(half3 color,sampler2D s_depth,sampler s_color,sampler s_noise,sampler CubeLookup,float2 position,float4 texcoord,float3 direction,float4 texsize) 
{
	half shadow = 0.0f;
	float3 sample_direction = abs(texcoord.xyz);
	float sample_maximum = max(max(sample_direction.x,sample_direction.y),sample_direction.z);
	#ifdef ATI_R700 || ATI_R800
		float3 sample_clamp = 127.0f / 128.0f + (sample_direction == sample_maximum) * (1.0f / 128.0f);
		sample_direction = clamp(texcoord.xyz / sample_maximum,-sample_clamp,sample_clamp);
	#else
		sample_direction = texcoord.xyz;
	#endif
	float4 sample_texcoord = float4(texCUBE(CubeLookup,sample_direction).xy,0.0f,1.0f);
	sample_texcoord.z = -1.0f / sample_maximum + texcoord.w;

	#ifdef QUALITY_HIGH
		half4 jitter_texcoord = half4(position * (1.0f / 16.0f),0.0f,0.0f);
		sample_texcoord.xy -= s_light_shadow_iradius.z;
		#ifdef HAS_NVIDIA_HARDWARE_SHADOW
			#define SAMPLE { \
				half4 jitter = tex3Dlod(s_noise,jitter_texcoord) * s_light_shadow_iradius.w; \
				shadow += tex2Dlod(s_depth,float4(sample_texcoord.xyz + half3(jitter.xy,0.0f),0.0f)).x; \
				shadow += tex2Dlod(s_depth,float4(sample_texcoord.xyz + half3(jitter.zw,0.0f),0.0f)).x; \
				jitter_texcoord.z += 1.0f / 16.0f; \
			}
		#elif HAS_ATI_HARDWARE_SHADOW
			#define SAMPLE { \
				half4 jitter = tex3Dlod(s_noise,jitter_texcoord) * s_light_shadow_iradius.w; \
				shadow += (sample_texcoord.z < tex2Dlod(s_depth,float4(sample_texcoord.xy + jitter.xy,0.0f,0.0f)).x); \
				shadow += (sample_texcoord.z < tex2Dlod(s_depth,float4(sample_texcoord.xy + jitter.zw,0.0f,0.0f)).x); \
				jitter_texcoord.z += 1.0f / 16.0f; \
			}
		#endif
		SAMPLE
		SAMPLE
		SAMPLE
		SAMPLE
		shadow *= 1.0f / 8.0f;
		#ifdef USE_SHADOW_KERNEL
			[branch] if(shadow * (1.0f - shadow) != 0.0f) {
				shadow *= 8.0f;
				[unroll] for(int i = 4; i < 16; i++) {
					SAMPLE
				}
				shadow *= 1.0f / 32.0f;
				#ifdef SHOW_PENUMBRA
					color = half3(1.0f,0.0f,0.0f);
				#endif
			}
		#endif
		#undef SAMPLE
	#else
		#ifdef HAS_NVIDIA_HARDWARE_SHADOW
			shadow = tex2Dproj(s_depth,sample_texcoord).x;
		#elif HAS_ATI_HARDWARE_SHADOW
			shadow = shadow2DLinear(s_depth,sample_texcoord.xy,texsize,sample_texcoord.z);
		#endif
	#endif
	color *= saturate(shadow + s_light_shadow_iradius.y);
	#ifdef USE_TRANSLUCENT
		half sample_distance = saturate(length(half3(direction)));
		half4 translucent = texCUBE(s_color,direction);
		[flatten] if(shadow > 0.0f && sample_distance > translucent.w) color *= saturate(translucent.xyz + s_light_shadow_iradius.y);
	#endif
	return color;
}

/*
 */
half3 shadowOmniVertexPCF(half3 color,sampler s_depth,sampler s_color,sampler s_noise,sampler CubeLookup,float2 position,float3 WorldPos,float4 texsize) 
{
	// remap world 
	float3 ShadowViewPos = WorldPos - 

	float4 shadow_direction;
	float3 direction = mul3(s_imodelview,vertex.xyz - s_light_shadow_offset);
	shadow_direction.xyz = direction * s_light_shadow_depth_range.x;
	shadow_direction.w = s_light_shadow_depth_range.y;
	#ifdef USE_TRANSLUCENT
		direction *= s_light_shadow_iradius.x;
	#endif
	return VOmniShadowPCF(color,s_depth,CubeLookup,s_noise,CubeLookup,position,shadow_direction,direction,texsize);
}



/*
 */
#ifdef SHADOW
	#ifdef USE_TRANSLUCENT
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_texture_12,s_texture_14,s_texture_15,IN.position,IN.texcoord_4,IN.texcoord_5,s_material_textures[13]);
	#else
		#define SHADOW_OMNI_PCF(COLOR) COLOR = VOmniShadowPCF(COLOR,s_texture_13,s_texture_12,s_texture_14,s_texture_15,IN.position,IN.texcoord_4,0.0f,s_material_textures[13]);
	#endif
#else
	#define SHADOW_OMNI_PCF(COLOR) { }
#endif

/*
 */
#ifdef SHADOW
	#define SHADOW_OMNI_VERTEX_PCF(COLOR,VERTEX) COLOR = shadowOmniVertexPCF(COLOR,s_texture_13,s_texture_12,s_texture_14,s_texture_15,IN.position,VERTEX,s_material_textures[13]);
#else
	#define SHADOW_OMNI_VERTEX_PCF(COLOR,VERTEX) { }
#endif

#endif /* __FRAGMENT_BASE_SHADOW_OMNI_H__ */
